package com.ynet.middleground.user.model;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ynet.core.common.PagerInfo;
import com.ynet.core.exception.BusinessException;
import com.ynet.middleground.user.bean.AddUserRoleRelationReq;
import com.ynet.middleground.user.bean.DeleteAddUserRoleRelationReq;
import com.ynet.middleground.user.bean.QueryUserRoleRelationListReq;
import com.ynet.middleground.user.bean.QueryUserRoleRelationReq;
import com.ynet.middleground.user.common.SystemConstant;
import com.ynet.middleground.user.bean.*;
import com.ynet.middleground.user.dao.*;
import com.ynet.middleground.user.dto.*;
import com.ynet.middleground.user.entity.*;
import com.ynet.middleground.user.utils.GeneralService;

/**
 * @description: 用户角色关系管理模块
 * @author: Wangxz
 * @create: 2019-11-25 16:52
 **/
@Component
public class UserRoleRelationModel extends ServiceImpl<UserRoleRelationMapper, UserRoleRelation> {

    @Autowired
    UserBaseInformationMapper userBaseInformationMapper;

    @Autowired
    EnterpriseUserInfoMapper enterpriseUserInfoMapper;

    @Autowired
    EnterpriseUserRoleMapper enterpriseUserRoleMapper;

    @Autowired
    UserRoleRelationMapper userRoleRelationMapper;

    @Autowired
    Mapper mapper;

    @Autowired
    GeneralService generalService;

    @Autowired
    EnterpriseBasicInfoMapper enterpriseBasicInfoMapper;

    @Autowired
    ChannelConfigMapper channelConfigMapper;

    @Autowired
    OrganizationalStructureMapper organizationalStructureMapper;

    @Autowired
    private ChannelConfigModel channelConfigModel;

    @Autowired
    private OrganizationManagementModel organizationManagementModel;

    private static final String queryChannelSplitFlag = ",";

    /**
     * 员工角色关系添加
     *
     * @param addUserRoleRelationReq
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void addUserRoleRelation(AddUserRoleRelationReq addUserRoleRelationReq) throws Exception {
        // 验证用户真实性
        verifcationUserInFo(addUserRoleRelationReq);
        // 验证企业员工角色真实性
        verifcationRoleInFo(addUserRoleRelationReq.getRoleId());
        // 验证用户关系是否存在
        verificationUserRoleRelation(addUserRoleRelationReq);
        // 将请求信息入库
        UserRoleRelation userRoleRelation = mapper.map(addUserRoleRelationReq, UserRoleRelation.class);
        userRoleRelation.setCreateBy(addUserRoleRelationReq.getOperationUserId());
        userRoleRelation.setGmtCreate(LocalDateTime.now());
        if (!this.save(userRoleRelation)) {
            throw new BusinessException("用户角色关系添加失败！", "EB00001");
        }
    }

    /**
     * 员工角色关系删除
     *
     * @param requestObject
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteUserRoleRelation(DeleteAddUserRoleRelationReq requestObject) throws Exception {
        LambdaQueryWrapper<UserRoleRelation> userRoleRelationQueryWrapper = new LambdaQueryWrapper<>();
//        if (generalService.isJoinUnfinishedProcess(requestObject.getUserId(), requestObject)) {
//            throw new BusinessException("当前用户存在代办，无法删除角色关系", "BE00001");
//        }
        userRoleRelationQueryWrapper.eq(UserRoleRelation::getUserId, requestObject.getUserId());
        userRoleRelationQueryWrapper.eq(UserRoleRelation::getRoleId, requestObject.getRoleId());
        userRoleRelationQueryWrapper.eq(UserRoleRelation::getEnterpriseId, requestObject.getEnterpriseId());
        userRoleRelationQueryWrapper.eq(UserRoleRelation::getChannel, requestObject.getChannel());
        if (!this.remove(userRoleRelationQueryWrapper)) {
            throw new BusinessException("删除失败", "BE00001");
        }
    }

    /**
     * 分页查询角色关系
     *
     * @param queryUserRoleRelationReq
     * @return
     * @throws Exception
     */
    public List<UserRoleRelationDto> queryUserRoleRelationList(QueryUserRoleRelationReq queryUserRoleRelationReq)
        throws Exception {
        // 获取分页信息
        PagerInfo pagerInfo = queryUserRoleRelationReq.getPagerInfo();
        // 获取总条数
        pagerInfo.setTotal(this.count());
        LambdaQueryWrapper<UserRoleRelation> userRoleRelationQueryWrapper = new LambdaQueryWrapper<>();
        if (null != queryUserRoleRelationReq.getUserId()) {
            userRoleRelationQueryWrapper.eq(UserRoleRelation::getUserId, queryUserRoleRelationReq.getUserId());
        }
        if (null != queryUserRoleRelationReq.getRoleId()) {
            userRoleRelationQueryWrapper.eq(UserRoleRelation::getRoleId, queryUserRoleRelationReq.getRoleId());
        }
        if (null != queryUserRoleRelationReq.getEnterpriseId()) {
            userRoleRelationQueryWrapper.eq(UserRoleRelation::getEnterpriseId,
                queryUserRoleRelationReq.getEnterpriseId());
        }
        if (StringUtils.isNotEmpty(queryUserRoleRelationReq.getQueryChannel())) {
            List<String> queryChannelList =
                Arrays.asList(queryUserRoleRelationReq.getQueryChannel().split(queryChannelSplitFlag));
            userRoleRelationQueryWrapper.in(UserRoleRelation::getChannel, queryChannelList);
        }
        // 分页查询用户角色关系
        IPage<UserRoleRelation> userRoleRelationIPage =
            this.page(new Page<>(pagerInfo.getPageNum(), pagerInfo.getPageSize()), userRoleRelationQueryWrapper);
        List<UserRoleRelation> userRoleRelations = userRoleRelationIPage.getRecords();
        List<UserRoleRelationDto> userRoleRelationDtos = new ArrayList<>();
        if (null != userRoleRelations) {
            userRoleRelationDtos = userRoleRelations.stream().map(x -> mapper.map(x, UserRoleRelationDto.class))
                .collect(Collectors.toList());
            queryUserRoleRelationReq.setPagerInfo(pagerInfo);
            return userRoleRelationDtos;
        }
        return userRoleRelationDtos;
    }

    /**
     * 查询角色关系
     * 
     * @param queryUserRoleRelationListReq
     * @return
     */
    public List<UserRoleRelationDto>
        queryUserRoleRelationInfo(QueryUserRoleRelationListReq queryUserRoleRelationListReq) {
        LambdaQueryWrapper<UserRoleRelation> userRoleRelationQueryWrapper = new LambdaQueryWrapper<>();
        if (null != queryUserRoleRelationListReq.getUserId()) {
            userRoleRelationQueryWrapper.eq(UserRoleRelation::getUserId, queryUserRoleRelationListReq.getUserId());
        }
        if (null != queryUserRoleRelationListReq.getRoleId()) {
            userRoleRelationQueryWrapper.eq(UserRoleRelation::getRoleId, queryUserRoleRelationListReq.getRoleId());
        }
        if (null != queryUserRoleRelationListReq.getEnterpriseId()) {
            userRoleRelationQueryWrapper.eq(UserRoleRelation::getEnterpriseId,
                queryUserRoleRelationListReq.getEnterpriseId());
        }
        if (StringUtils.isNotEmpty(queryUserRoleRelationListReq.getQueryChannel())) {
            List<String> queryChannelList =
                Arrays.asList(queryUserRoleRelationListReq.getQueryChannel().split(queryChannelSplitFlag));
            userRoleRelationQueryWrapper.in(UserRoleRelation::getChannel, queryChannelList);
        }
        List<UserRoleRelationDto> userRoleRelations = new ArrayList<>();
        List<UserRoleRelation> roleRelations = this.list(userRoleRelationQueryWrapper);
        if (null != roleRelations) {
            userRoleRelations =
                roleRelations.stream().map(x -> mapper.map(x, UserRoleRelationDto.class)).collect(Collectors.toList());
        }

        return userRoleRelations;
    }

    /**
     * 港内员工组织机构信息查询
     *
     * @return
     * @throws Exception
     */
    public List<QueryOrganizationalStructureDto> queryOrganizationalStructureList() throws Exception {
        List<Map<String, Object>> mapList = userRoleRelationMapper.queryOrganizationalStructure();
        List<QueryOrganizationalStructureDto> dtoList = new ArrayList<>();
        if (null == mapList) {
            return dtoList;
        }
        Set<String> channelSet = new HashSet<>();
        for (Map<String, Object> map : mapList) {
            QueryOrganizationalStructureDto dto = new QueryOrganizationalStructureDto();
            //20220623syf增加上级渠道
            if("0".equals(map.get("flag"))){
                channelSet.add((String)map.get("channel"));
            }
            String parentId = "" + map.get("parent_id");
            if("0".equals(parentId)||map.get("id").equals(parentId)){
                dto.setParentId((String)map.get("channel"));
            }else{
                dto.setParentId("" + map.get("parent_id"));
            }
            //end
            dto.setId((String)map.get("id"));
            dto.setName((String)map.get("name"));
            dto.setVal((String)map.get("val"));
            dto.setChannel((String)map.get("channel"));
            dtoList.add(dto);
            dto = null;
        }
        //20220623syf增加上级渠道
        List<ChannelDTO> channelList = channelConfigModel.listAll();
        for(ChannelDTO oneChannel:channelList){
            if(channelSet.contains(oneChannel.getChannelCode())) {
                QueryOrganizationalStructureDto dto = new QueryOrganizationalStructureDto();
                dto.setParentId("");
                dto.setId(oneChannel.getChannelCode());
                dto.setName(oneChannel.getChannelCode()+"-"+oneChannel.getChannelName());
                dto.setVal(oneChannel.getChannelName());
                dto.setChannel(oneChannel.getChannelCode());
                dto.setNoCheck("true");
                dtoList.add(dto);
                dto = null;
            }
        }
        //end
        return dtoList;
    }

    /**
     * 上下级
     *
     * @param operateChannels 可操作渠道列表，例：T01,T02
     * @param id
     * @return
     */
    public List<String> parentAndChildOrganizations(String operateChannels, Integer id) {
        List<String> parentAndChildOrganizations = new ArrayList<>(10);
        // 父
        List<String> parentOrganizations = parentOrganizations(operateChannels, id, null);
        if (parentOrganizations != null && parentOrganizations.size() > 0) {
            parentAndChildOrganizations.addAll(parentOrganizations);
        }
        // 子
        List<String> childOrganizations = childOrganizations(operateChannels, id, null);
        if (childOrganizations != null && childOrganizations.size() > 0) {
            parentAndChildOrganizations.addAll(childOrganizations);
        }
        parentAndChildOrganizations = parentAndChildOrganizations.stream().distinct().collect(Collectors.toList());
        return parentAndChildOrganizations;
    }

    /**
     * 取出父组织Id
     *
     * @Param operateChannels 可操作渠道列表，例：T01,T02
     * @param id 组织Id
     * @return parentIds 父组织Id
     */
    public List<String> parentOrganizations(String operateChannels, Integer id, List<String> parentIds) {
        if (id == null) {
            return null;
        }
        if (parentIds == null || parentIds.size() == 0) {
            parentIds = new ArrayList<>(10);
        }
        LambdaQueryWrapper<OrganizationalStructure> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrganizationalStructure::getOrganizationalId, id);
        if (StringUtils.isNotEmpty(operateChannels)) {
            queryWrapper.in(OrganizationalStructure::getChannel, Arrays.asList(operateChannels.split(",")));
        }
        OrganizationalStructure organizationalStructure = organizationalStructureMapper.selectOne(queryWrapper);
        if (organizationalStructure != null) {
            // 还有上一级
            if (organizationalStructure.getParentId() != 0) {
                parentIds.add("d:" + String.valueOf(organizationalStructure.getParentId()));
                parentOrganizations(operateChannels, organizationalStructure.getParentId(), parentIds);
            }
        }
        return parentIds;
    }

    /**
     * 取出子组织Id
     *
     * @Param operateChannels 可操作渠道列表，例：T01,T02
     *
     * @param id 组织Id
     * @return 子组织Id
     */
    public List<String> childOrganizations(String operateChannels, Integer id, List<String> childIds) {
        if (id == null) {
            return null;
        }
        if (childIds == null || childIds.size() == 0) {
            childIds = new ArrayList<>(10);
        }
        LambdaQueryWrapper<OrganizationalStructure> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrganizationalStructure::getParentId, id);
        if (StringUtils.isNotEmpty(operateChannels)) {
            queryWrapper.in(OrganizationalStructure::getChannel, Arrays.asList(operateChannels.split(",")));
        }
        List<OrganizationalStructure> organizationalStructures = organizationalStructureMapper.selectList(queryWrapper);
        // 有下一级
        if (organizationalStructures != null && organizationalStructures.size() > 0) {
            for (OrganizationalStructure o : organizationalStructures) {
                childIds.add("d:" + o.getOrganizationalId());
                childOrganizations(operateChannels, o.getOrganizationalId(), childIds);
            }
        }
        return childIds;
    }

    /**
     * 港内员工数据查询（移动审批专用）
     *
     * @return
     * @throws Exception
     */
    public List<DingTalkSearchEmployeesDTO> queryEmployeesForMobile(DingTalkSearchEmployeesInfoReq req) {
        // step1: 查询员工、角色、组织等
        List<DingTalkSearchEmployeesDTO> employees = new ArrayList<>(10);
        List<Map<String, Object>> list = null;
        try {
            list = userRoleRelationMapper.queryEmployeesForMobile(req);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (null == list) {
            return employees;
        }
        for (Map<String, Object> map : list) {
            DingTalkSearchEmployeesDTO dto = new DingTalkSearchEmployeesDTO();
            dto.setUniqueKey((String)map.get("uniqueKey"));
            dto.setParentId((String)map.get("parentId"));
            dto.setId((String)map.get("id"));
            dto.setName((String)map.get("name"));
            dto.setChannel((String)map.get("channel"));
            dto.setChannelName((String)map.get("channelName"));
            dto.setType((String)map.get("type"));
            dto.setOtherMessage((String)map.get("otherMessage"));
            employees.add(dto);
            dto = null;
        }
        return employees;
    }

    /**
     * 查询企业组织结构
     *
     * @return
     * @throws Exception
     */
    public List<QueryCorporateOrganizationRoleDto> queryCorporateOrganizationRole() throws Exception {
        List<Map<String, Object>> mapList = userRoleRelationMapper.queryBusinessRole();
        List<QueryCorporateOrganizationRoleDto> dtoList = new ArrayList<>();
        if (null == mapList) {
            return dtoList;
        }
        for (Map<String, Object> map : mapList) {
            QueryCorporateOrganizationRoleDto queryDto = new QueryCorporateOrganizationRoleDto();
            queryDto.setName((String)map.get("name"));
            queryDto.setId("" + map.get("id"));
            queryDto.setVal((String)map.get("val"));
            queryDto.setParentId("" + map.get("parent_id"));
            dtoList.add(queryDto);
            queryDto = null;
        }

        return dtoList;
    }

    /**
     * 企业员工信息查询
     *
     * @return
     * @throws Exception
     */
    public List<QueryEnterpriseUserInfoDto> queryEnterpriseUserInfo() throws Exception {
        List<QueryEnterpriseUserInfoDto> userInfoDtos = new ArrayList<>();
        LambdaQueryWrapper<UserBaseInformation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserBaseInformation::getUserType, "3");
        queryWrapper.or();
        queryWrapper.eq(UserBaseInformation::getUserType, "0");
        queryWrapper.orderByDesc(UserBaseInformation::getUserId);
        List<UserBaseInformation> userBaseInformations = userBaseInformationMapper.selectList(queryWrapper);
        if (null == userBaseInformations) {
            return userInfoDtos;
        }
        for (UserBaseInformation userInfo : userBaseInformations) {
            // QueryEnterpriseUserInfoDto dto = new QueryEnterpriseUserInfoDto();
            // dto.setUserId(userInfo.getUserId().toString());
            // dto.setUserName(userInfo.getUserName());
            LambdaQueryWrapper<EnterpriseUserInfo> queryWrapperEBI = new LambdaQueryWrapper<>();
            queryWrapperEBI.eq(EnterpriseUserInfo::getUserId, userInfo.getUserId());
            queryWrapperEBI.orderByDesc(EnterpriseUserInfo::getUserId);
            List<EnterpriseUserInfo> enterpriseUserInfoLists = enterpriseUserInfoMapper.selectList(queryWrapperEBI);
            for (int i = 0; i < enterpriseUserInfoLists.size(); i++) {
                QueryEnterpriseUserInfoDto dto = new QueryEnterpriseUserInfoDto();
                // add by liwq on 2020-12-08 start
                // 添加企业名称
                Integer entOperatorId = enterpriseUserInfoLists.get(i).getEntOperatorId();
                LambdaQueryWrapper<EnterpriseBasicInfo> query = new LambdaQueryWrapper<>();
                query.eq(EnterpriseBasicInfo::getUserId, entOperatorId);
                query.isNull(EnterpriseBasicInfo::getDeleteChannelUsers);
                EnterpriseBasicInfo e = enterpriseBasicInfoMapper.selectOne(query);
                // add by liwq on 2020-12-08 end
                EnterpriseUserInfo enterpriseUserInfo = enterpriseUserInfoLists.get(i);
                // 根据渠道编码，找出渠道名称 start
                List<ChannelConfig> channelConfigs = new ArrayList<>();
                LambdaQueryWrapper<ChannelConfig> q = new LambdaQueryWrapper<>();
                String channel = enterpriseUserInfo.getChannel();
                String channelName = null;
                if (!StringUtils.isEmpty(channel)) {
                    q.eq(ChannelConfig::getIsDeleted, 0);
                    q.eq(ChannelConfig::getChannelCode, channel);
                    channelConfigs = channelConfigMapper.selectList(q);
                    if (channelConfigs.size() > 0) {
                        channelName = channelConfigs.get(0).getChannelName();
                    }
                }
                // 根据渠道编码，找出渠道名称 End
                dto.setUserId(enterpriseUserInfo.getUserId().toString());
                dto.setUserName(enterpriseUserInfo.getUserName());
                dto.setEnterpriseId(enterpriseUserInfo.getEntOperatorId());
                dto.setEnterpriseName(e.getCompanyName());
                dto.setChannel(enterpriseUserInfo.getChannel());
                dto.setChannelName(channelName);
                userInfoDtos.add(dto);
                dto = null;
            }
        }
        return userInfoDtos;
    }

    /**
     * 港内员工信息查询
     *
     * @return
     * @throws Exception
     */
    public List<QueryPortUserInfoDto> queryPortUserInfoList() throws Exception {
        List<QueryPortUserInfoDto> userInfoDtos = new ArrayList<>();
        List<Map<String, Object>> mapList = userRoleRelationMapper.queryPortUserInfoList();
        if (null == mapList) {
            return userInfoDtos;
        }
        for (Map<String, Object> map : mapList) {
            List<ChannelConfig> channelConfigs = new ArrayList<>();
            LambdaQueryWrapper<ChannelConfig> query = new LambdaQueryWrapper<>();
            // 根据渠道编码，找出渠道名称 start
            String channel = (String)map.get("channel");
            String channelName = null;
            if (!StringUtils.isEmpty(channel)) {
                query.eq(ChannelConfig::getIsDeleted, 0);
                query.eq(ChannelConfig::getChannelCode, channel);
                channelConfigs = channelConfigMapper.selectList(query);
                if (channelConfigs.size() > 0) {
                    channelName = channelConfigs.get(0).getChannelName();
                }
            }
            // 根据渠道编码，找出渠道名称 End
            QueryPortUserInfoDto queryDto = new QueryPortUserInfoDto();
            queryDto.setUserId(map.get("user_id") == null ? null : map.get("user_id").toString());
            queryDto.setUserName((String)map.get("user_name"));
            queryDto.setEmployeeNo((String)map.get("employee_no"));
            queryDto.setChannel(channel);
            queryDto.setChannelName(channelName);
            queryDto.setOrganizationalId(
                map.get("organizational_id") == null ? null : map.get("organizational_id").toString());
            queryDto.setOrganizationalName((String)map.get("organizational_name"));
            OrganizationalStructure temp = new OrganizationalStructure();
            if(map.get("organizational_id")!=null) {
                Integer parentId = Integer.valueOf(map.get("parent_id").toString());
                Integer organizationalId = Integer.valueOf(map.get("organizational_id").toString());
                temp.setParentId(parentId);
                temp.setOrganizationalId(organizationalId);
                temp.setOrganizationalName((String)map.get("organizational_name"));
                temp = organizationManagementModel.selectFormatIdByOrganizational(temp);
                queryDto.setFormatId(temp.getOrganizationalId());
                queryDto.setFormatName(temp.getOrganizationalName());
            }
            userInfoDtos.add(queryDto);
            queryDto = null;
        }
        return userInfoDtos;
    }

    /**
     * 验证用户关系是否存在
     *
     * @param req
     * @return
     * @throws BusinessException
     */
    public void verificationUserRoleRelation(AddUserRoleRelationReq req) throws BusinessException {
        LambdaQueryWrapper<UserRoleRelation> userRoleRelationQueryWrapper = new LambdaQueryWrapper<>();
        userRoleRelationQueryWrapper.eq(UserRoleRelation::getUserId, req.getUserId());
        userRoleRelationQueryWrapper.eq(UserRoleRelation::getRoleId, req.getRoleId());
        userRoleRelationQueryWrapper.eq(UserRoleRelation::getEnterpriseId, req.getEnterpriseId());
        userRoleRelationQueryWrapper.eq(UserRoleRelation::getChannel, req.getChannel());
        if (this.count(userRoleRelationQueryWrapper) != 0) {
            throw new BusinessException("该用户已拥有该角色！", "BE00001");
        }
    }

    /**
     * 验证用户真实性
     *
     * @param req
     * @return
     * @throws BusinessException
     */
    public void verifcationUserInFo(AddUserRoleRelationReq req) throws BusinessException {
        LambdaQueryWrapper<EnterpriseUserInfo> enterpriseUserInfoQueryWrapper = new LambdaQueryWrapper<>();
        enterpriseUserInfoQueryWrapper.eq(EnterpriseUserInfo::getUserId, req.getUserId());
        enterpriseUserInfoQueryWrapper.eq(EnterpriseUserInfo::getEntOperatorId, req.getEnterpriseId());
        enterpriseUserInfoQueryWrapper.eq(EnterpriseUserInfo::getChannel, req.getChannel());
        enterpriseUserInfoQueryWrapper.eq(EnterpriseUserInfo::getIsDelete, SystemConstant.IS_DELETE_0);
        if (enterpriseUserInfoMapper.selectCount(enterpriseUserInfoQueryWrapper) != 1) {
            throw new BusinessException("该企业员工用户不存在", "EB00001");
        }
    }

    /**
     * 验证企业员工角色真是性
     *
     * @param roleId
     * @throws BusinessException
     */
    public void verifcationRoleInFo(Integer roleId) throws BusinessException {
        QueryWrapper<EnterpriseUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", roleId);
        if (enterpriseUserRoleMapper.selectCount(queryWrapper) != 1) {
            throw new BusinessException("该企业员工角色不存在", "EB00001");
        }
    }

}
